package 多线程.Threadpool;

import java.util.concurrent.*;

/**
 * @Author kirito
 * @Date 2023/12/19 13:58
 * @PackageName:多线程.Threadpool
 * @ClassName: ThreadPoolTest
 * @Description:
 * @Version 1.0
 */
public class ThreadPoolTest {
    public static void main(String[] args) {
        /**
         * public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
         *         return new FinalizableDelegatedExecutorService
         *             (new ThreadPoolExecutor(1, 1,
         *                                     0L, TimeUnit.MILLISECONDS,
         *                                     new LinkedBlockingQueue<Runnable>(),
         *                                     threadFactory));
         *     }
         * 可以看到它的核心线程数和最大线程数都是1，其它参数都和FixedThreadPool相同，既然它是单线程，那么就可以保证任务的顺序执行。
         */
        ExecutorService executorService2 = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());

        /**
         * 这是一个会根据需要创建新线程的线程池，也就是大小可变的线程池，下面是它的源码：
         *
         * public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
         *         return new FinalizableDelegatedExecutorService
         *             (new ThreadPoolExecutor(1, 1,
         *                                     0L, TimeUnit.MILLISECONDS,
         *                                     new LinkedBlockingQueue<Runnable>(),
         *                                     threadFactory));
         *
         * 可以看到，核心线程数为0，最大线程数为Integer的最大值（可以理解为无界），
         * CachedThreadPool使用没有容量的SynchronousQueue（上面有提到过）作为线程池的工作队列，
         * 但最大线程数是无界的，这就意味着：如果主线程提交任务的速度高于CachedThreadPool线程处理任务的速度时，
         * CachedThreadPool会不断地创建新线程。
         *
         * ps：极端情况下，Cached会因为创建过多的线程而耗尽CPU和内存资源。
         */
        ExecutorService executorService = Executors.newCachedThreadPool();

        /**
         * 用来执行大任务的线程池，WorkStealingPool可以自适应地调整线程池大小，它会根据处理器核数创建相应数量的线程池
         *
         * 可以看出，ForkJoinPool的构造函数被调用来创建WorkStealingPool线程池，
         * Runtime.getRuntime().availableProcessors()来获取处理器的核心数量，来作为线程池的大小：
         *
         * 为什么说它是执行大任务的线程池呢？因为它本质是一个ForkJoinPool，而ForkJoinPool有一个工作窃取的概念：
         * 工作窃取：当我去执行一个特别大的任务时，感觉我用一个线程去执行的时候周期会很长，
         * 那么我可以通过自己的业务去把他拆分成很多很多个小的业务，比如我的任务需要5分钟，那么我把它拆分成10个，
         * 可能就半分种就搞定了，然后再把这10个任务交给newWorkStealingPool线程池，找一些没事干的线程去帮我干这个任务
         */
        ExecutorService executorService3 = Executors.newWorkStealingPool();

        /**
         * 可重用固定线程数的线程池
         * 可以看到，核心线程数（corePoolSize）和最大线程数（maximumPoolSize）都是传进来的nThreads，
         * 这就意味着这个数量在其生命周期内不会变化，
         * 当线程池中的线程都在工作时，新提交的任务会被放置到一个无界队列中（没有设置初始大小）等待被执行。
         */
        ExecutorService executorService1 = Executors.newFixedThreadPool(5, Executors.defaultThreadFactory());

        /**
         *     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
         *         return new ScheduledThreadPoolExecutor(corePoolSize);
         *     }
         *     public static ScheduledExecutorService newScheduledThreadPool(
         *             int corePoolSize, ThreadFactory threadFactory) {
         *         return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
         *     }
         *  可以看到核心线程数是传进来的，最大线程数为Integer的最大值，工作队列用的是DelayWorkQueue延迟队列、无界。
         */
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);

    }
}
